package com.question.service.impl;

import com.question.constant.MessageConstant;
import com.question.constant.StatusConstant;
import com.question.context.BaseContext;
import com.question.exception.*;
import com.question.mapper.UserAnswerMapper;
import com.question.mapper.UserFavoriteMapper;
import com.question.mapper.UserMapper;
import com.question.pojo.dto.*;
import com.question.pojo.entity.User;
import com.question.pojo.result.PageResult;
import com.question.pojo.vo.UserVO;
import com.question.pojo.vo.UserAnswerVO;
import com.question.pojo.vo.UserSortVO;
import com.question.utils.RedisUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.question.service.UserService;
import org.springframework.util.DigestUtils;

import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Service
@Slf4j
public class UserServiceImpl implements UserService {

    @Autowired
    private UserMapper userMapper;

    @Autowired
    private RedisUtil redisUtil;

    @Autowired
    private UserAnswerMapper userAnswerMapper;

    @Autowired
    private UserFavoriteMapper userFavoriteMapper;

    /**
     * 用户登录
     * @param userLoginDTO
     * @return
     */
    public User login(UserLoginDTO userLoginDTO) {
        String username = userLoginDTO.getUsername();
        String password = userLoginDTO.getPassword();

        //1、根据用户名查询数据库中的数据
        User user = userMapper.getByUsername(username, MessageConstant.NOT_EXCLUDED);

        //2、处理各种异常情况（用户名不存在、密码不对、账号被锁定）
        if (user == null) {
            //账号不存在
            throw new AccountNotFoundException(MessageConstant.ACCOUNT_NOT_FOUND);
        }

        //密码比对, 明文密码加密处理
        password = DigestUtils.md5DigestAsHex(password.getBytes());
        if (!password.equals(user.getPasswordHash())) {
            //密码错误
            throw new PasswordErrorException(MessageConstant.PASSWORD_ERROR);
        }

        return user;
    }

    /**
     * 退出登录
     * @param token
     */
    public void logout(String token) {
        try {
            redisUtil.deleteObject(token);
        } catch (Exception e) {
            log.error(MessageConstant.LOGOUT_EXCEPTION, e);
            throw new LogoutFailedException(MessageConstant.LOGOUT_EXCEPTION);
        }
    }

    /**
     * 用户注册
     * @param userRegisterDTO
     */
    public void register(UserRegisterDTO userRegisterDTO) {
        String username = userRegisterDTO.getUsername();
        String password = userRegisterDTO.getPassword();
        String rePassword = userRegisterDTO.getRePassword();
        String email = userRegisterDTO.getEmail();

        User user = userMapper.getByUsername(username, MessageConstant.NOT_EXCLUDED);

        //判断用户名是否已经存在
        if (user != null) {
            throw new UserExistException(MessageConstant.USER_ALREADY_EXISTS);
        }

        Boolean emailIsExist = userMapper.findByEmail(email, MessageConstant.NOT_EXCLUDED);

        //判断邮箱是否已存在
        if (emailIsExist != null && emailIsExist) {
            throw new EmailExistException(MessageConstant.EMAIL_ALREADY_EXISTS);
        }

        //判断两次密码是否一致
        if (!password.equals(rePassword)) {
            throw new PasswordErrorException(MessageConstant.REPWD_NOTEQUAL_NEW);
        }

        password = DigestUtils.md5DigestAsHex(password.getBytes());
        //创建用户
        user = User.builder()
                .username(username)
                .passwordHash(password)
                .email(userRegisterDTO.getEmail())
                .isAdmin(StatusConstant.NOT_ADMIN)
                .professional(userRegisterDTO.getProfessional())
                .build();

        userMapper.insert(user);
    }

    /**
     * 修改个人信息
     * @param userDTO
     */
    public void modifyInfo(UserDTO userDTO) {
        Long userId = BaseContext.getCurrentId();
        String username = userDTO.getUsername();
        String email = userDTO.getEmail();

        //判断用户是否已经存在(用户名唯一)
        if(username != null && username != ""){
            User getUser = userMapper.getByUsername(username, userId);
            if(getUser != null){
                throw new UserExistException(MessageConstant.USER_ALREADY_EXISTS);
            }
        }

        //判断邮箱是否已绑定账户(邮箱唯一)
        if(email != null && email != ""){
            Boolean emailIsExist = userMapper.findByEmail(email, userId);
            if(emailIsExist != null && emailIsExist){
                throw new EmailExistException(MessageConstant.EMAIL_ALREADY_EXISTS);
            }
        }

        User user = new User();
        user.setUserId(BaseContext.getCurrentId());
        BeanUtils.copyProperties(userDTO, user);

        userMapper.modify(user);
    }

    /**
     * 修改密码
     * @param userRepasswordDTO
     */
    public void editPassword(UserRepasswordDTO userRepasswordDTO, String token) {
        Long userId = BaseContext.getCurrentId();
        User getUser = userMapper.getById(userId);
        if (getUser == null) {
            throw new PasswordEditFailedException(MessageConstant.USER_NOT_LOGIN);
        }

        //旧密码比对
        String oldPasswordHash = DigestUtils.md5DigestAsHex(userRepasswordDTO.getOldPassword().getBytes());
        if (!getUser.getPasswordHash().equals(oldPasswordHash)) {
            throw new PasswordEditFailedException(MessageConstant.OLDPASSWORD_ERROR);
        }

        //新旧密码比对
        String newPassword = userRepasswordDTO.getNewPassword();
        if (newPassword.equals(userRepasswordDTO.getOldPassword())) {
            throw new PasswordEditFailedException(MessageConstant.OLDPWD_EQUAL_NEW);
        }

        String newPasswordHash = DigestUtils.md5DigestAsHex(newPassword.getBytes());

        User user = User.builder()
                .userId(userId)
                .passwordHash(newPasswordHash)
                .build();

        try  {
            userMapper.modify(user);
            redisUtil.deleteObject(token);
        } catch (Exception e) {
            throw new PasswordEditFailedException(MessageConstant.PASSWORD_EDIT_FAILED);
        }
    }

    /**
     * 根据id查询用户信息
     * @return
     */
    public User getById() {
        User user = userMapper.getById(BaseContext.getCurrentId());
        user.setPasswordHash("******");
        return user;
    }

    /**
     * 获取所有用户排行信息
     * @return
     */
    public UserSortVO getSortAll() {
        //获取所有用户答题信息
        List<UserAnswerVO> userAnswerList = userAnswerMapper.getUserAnswerInfo();
        Integer answerCountAll = 0;
        Double correctRateAll = 0.00;
        for (UserAnswerVO userAnswerVO : userAnswerList) {
            //计算个人答题数
            //计算个人正确率
            answerCountAll += userAnswerVO.getAnswerCount();
            if(userAnswerVO.getAnswerCount() == 0){
                userAnswerVO.setCorrectRate("0.00%");
                continue;
            }
            Integer correctCount = userAnswerMapper.getCorrectCount(userAnswerVO.getUserId());
            correctRateAll += (double) correctCount / userAnswerVO.getAnswerCount();
            userAnswerVO.setCorrectRate(String.format("%.2f%%", (double) correctCount / userAnswerVO.getAnswerCount() * 100));
        }

        //计算平均答题数和正确率
        Integer avgAnswerCount = answerCountAll / userAnswerList.size();
        String avgCorrectRate = String.format("%.2f%%", correctRateAll / userAnswerList.size() * 100);
        UserSortVO userSortVO = UserSortVO.builder()
                .avgAnswerCount(avgAnswerCount)
                .avgCorrectRate(avgCorrectRate)
                .perAnswerList(userAnswerList)
                .build();

        return userSortVO;
    }





    /**
     * 分页查询用户信息
     *
     * @param dto
     * @return
     */
    @Override
    public PageResult getUserPage(UserPageDTO dto) {
        int pageNum = dto.getPageNum() == null ? 1 : dto.getPageNum();
        int pageSize = dto.getPageSize() == null ? 10 : dto.getPageSize();
        int offset = (pageNum - 1) * pageSize;

        // 直接传递DTO字段值（不要用Map包装）
        List<UserVO> list = userMapper.selectUserPage(
                dto.getKeyword(),
                dto.getIsAdmin(),
                dto.getProfessional(),
                offset,
                pageSize
        );

        // 修复计数查询
        int total = userMapper.countUserPage(
                dto.getKeyword(),
                dto.getIsAdmin(),
                dto.getProfessional()
        );

        return new PageResult(total, list);
    }

    /**
     * 获取用户统计信息
     * @return
     */
    @Override
    public Map<String, Object> getUserStatistics() {
        Map<String, Object> result = new HashMap<>();
        result.put("adminCount", userMapper.countByAdminStatus(true));
        result.put("regularCount", userMapper.countByAdminStatus(false));

        UserStats stats = userMapper.getUserStats();
        result.put("avgAnswers", stats != null ? stats.getAvgAnswers() : 0.0);
        result.put("avgFavorites", stats != null ? stats.getAvgFavorites() : 0.0);

        return result;
    }

    @Override
    public UserStatisticsDTO getUserBehaviorStatistics(Long userId) {
        UserStatisticsDTO stats = new UserStatisticsDTO();

        try {
            // 获取答题统计数据
            AnswerStats answerStats = userAnswerMapper.getUserAnswerStats(userId);
            if (answerStats != null) {
                stats.setTotalAnswers(answerStats.getTotalAnswers());
                stats.setCorrectAnswers(answerStats.getCorrectAnswers());
                stats.setCorrectRate(answerStats.getCorrectRate());
            } else {
                // 设置默认值
                stats.setTotalAnswers(0);
                stats.setCorrectAnswers(0);
                stats.setCorrectRate(0.0);
            }

            // 获取收藏题目数量
            Integer favoriteCount = userFavoriteMapper.countUserFavorites(userId);
            stats.setFavoriteCount(favoriteCount != null ? favoriteCount : 0);

            // 获取专业领域分析
            List<MajorStatDTO> majorStats = userAnswerMapper.getUserMajorStats(userId);
            stats.setMajorStats(majorStats);

        } catch (Exception e) {
            log.error("获取用户行为统计失败: {}", e.getMessage());
            // 设置默认值
            stats.setTotalAnswers(0);
            stats.setCorrectAnswers(0);
            stats.setCorrectRate(0.0);
            stats.setFavoriteCount(0);
            stats.setMajorStats(Collections.emptyList());
        }

        return stats;
    }

    @Override
    public void toggleAdminStatus(Long userId, Boolean isAdmin) {
        User user = userMapper.getById(userId);
        if (user == null) {
            throw new AccountNotFoundException("用户不存在");
        }

        user.setAdmin(isAdmin);
        userMapper.modify(user);
    }

    /**
     * 重置用户密码
     * @param userId
     * @param newPassword
     */
    @Override
    public void resetPassword(Long userId, String newPassword) {
        User user = userMapper.getById(userId);
        if (user == null) {
            throw new AccountNotFoundException("用户不存在");
        }

        String newPasswordHash = DigestUtils.md5DigestAsHex(newPassword.getBytes());
        user.setPasswordHash(newPasswordHash);
        userMapper.modify(user);
    }

    /**
     * 修改用户信息
     * @param userDTO
     */
    @Override
    public void updateUser(UserDTO userDTO) {
        User user = userMapper.getById(userDTO.getUserId());
        if (user == null) {
            throw new AccountNotFoundException("用户不存在");
        }

        // 更新可修改字段
        if (userDTO.getProfessional() != null) {
            user.setProfessional(userDTO.getProfessional());
        }
        if (userDTO.getIsAdmin() != null) {
            user.setAdmin(userDTO.getIsAdmin());
        }
        if (userDTO.getEmail() != null) {
            user.setEmail(userDTO.getEmail());
        }

        userMapper.modify(user);
    }
}
